message 计算 SHA-512 摘要,然后和外部提供的 expectedHex 比较,判断两者是否一致。

async function verifySha512(message, expectedHex) {
  const data = str2ab(message);
  const hashBuf = await crypto.subtle.digest('SHA-512', data);
  const actualHex = ab2hex(hashBuf);
  return actualHex === expectedHex;
}

主要应用场景

1. 文件或内容完整性校验

例如服务端提供:

文件内容
expectedHash = SHA512(文件内容)

浏览器下载文件后重新计算:

const valid = await verifySha512(fileContent, expectedHash);

适合:

  • 下载文件校验

  • 配置文件校验

  • 大模型文件、安装包、镜像文件校验

  • 前端加载静态资源后验证内容

如果内容被修改,计算出的 Hash 就会不同。


2. 校验服务端返回的数据

例如接口返回:

{
  "data": "...",
  "sha512": "..."
}

前端可以验证:

const valid = await verifySha512(response.data, response.sha512);

适合检测:

  • 传输内容是否被篡改

  • 缓存内容是否发生变化

  • 本地存储内容是否损坏

但前提是 expectedHex 本身必须可信。如果攻击者可以同时修改消息和 expectedHex,这个校验就没有安全意义。


3. 前端校验固定内容

例如某个配置、模板或脚本内容必须符合预期:

const expectedHash = '...';
const isValid = await verifySha512(configText, expectedHash);

可以用于:

  • 判断内容是否发生变化

  • 检测本地缓存是否失效

  • 判断资源版本是否一致


4. 和后端约定内容摘要

前后端可能约定:

SHA-512(requestBody)

服务端或客户端通过比较摘要,确认内容是否一致。

不过如果目的是身份认证或防伪,不应只使用普通 SHA-512,而应该使用:

HMAC-SHA-512(secretKey, message)

普通 Hash 不包含密钥,任何人都可以重新计算。


重要限制

1. 不能用于密码验证

不要这样做:

verifySha512(password, storedHash)

因为 SHA-512 计算很快,容易被暴力破解。

密码应使用:

  • Argon2id

  • bcrypt

  • scrypt

  • PBKDF2


2. 不能证明内容来源可信

这段代码只能判断:

当前 message 是否对应 expectedHex

它不能证明:

message 一定来自可信服务器

例如攻击者把:

message
expectedHex

一起替换,比较仍然会成功。

如果需要防篡改和身份认证,应使用:

  • HTTPS

  • HMAC

  • 数字签名

  • 签名证书


3. expectedHex 应统一格式

需要确保:

  • 都是小写或都转小写

  • 没有多余空格

  • 长度应为 128 个十六进制字符

  • 编码方式一致,例如 UTF-8

可以改成:

async function verifySha512(message, expectedHex) {
  const data = new TextEncoder().encode(message);
  const hashBuf = await crypto.subtle.digest('SHA-512', data);

  const actualHex = [...new Uint8Array(hashBuf)]
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');

  return actualHex.toLowerCase() === expectedHex.trim().toLowerCase();
}

总结

这段代码适合:

验证字符串或数据内容是否和某个已知 SHA-512 摘要匹配。

典型用途是:

  • 文件完整性校验

  • 数据传输校验

  • 缓存内容校验

  • 版本内容判断

不适合:

  • 密码存储

  • 登录认证

  • 单独实现防伪或接口签名

  • 代替加密算法

如果 expectedHex 来自可信渠道,它可以用于完整性校验;如果还要防止攻击者伪造摘要,应改用 HMAC 或数字签名。